Introduction
Trying to calculate housing stress using 30/40 as in here: https://www.ahuri.edu.au/policy/ahuri-briefs/2016/3040-indicator
2016 Census - Counting Dwellings, Place of Enumeration (SA2)
Data Source: Census of Population and Housing, 2016, TableBuilder
Counting: Dwellings Location on Census Night
Variables:
- HIED Equivalised Total Household Income (weekly)
- RNTRD Rent (weekly) Ranges
- MRERD Mortgage Repayments (monthly) Ranges
library(tidyverse)
library(readxl)
library(sf)
library(tmap)
library(janitor)
library(scales)
Importing the raw data
##original files - 2016 census data - csv string - zeros suppressed
rentdata <- read_excel("sa2_data.xlsx", sheet = "sa2_hied_rntrd_2gmel_ zeros_sup", range = "A11:F49106") %>%
filter(GCCSA == "Greater Melbourne")
mortdata <- read_excel("sa2_data.xlsx", sheet = "sa2_hied_mrerd_2gmel_ zeros_sup", range = "A11:F59708") %>%
filter(GCCSA == "Greater Melbourne")
Midpoints for income
hhincwk_mid <- rentdata %>%
rename(sa2 = SA2) %>%
rename(hhincwk = `HIED Equivalised Total Household Income (weekly)`) %>%
mutate(hhincwk = as_factor(hhincwk)) %>%
distinct(hhincwk) %>%
filter(!hhincwk %in% c('Nil income', 'Partial income stated', 'All incomes not stated', 'Not applicable', 'Total')) %>%
mutate(inc_low = c(1, 150, 300, 400, 500, 650, 800, 1000, 1250, 1500, 1750, 2000, 2500, 3000)) %>%
mutate(inc_high = c(149, 299, 399, 499, 649, 799, 999, 1249, 1499, 1749, 1999, 2499, 2999, 3499)) %>%
mutate(inc_mid = (inc_low+inc_high)/2) %>%
select(hhincwk, inc_mid)
hhincwk_mid
Filter to include only bottom 40 per cent of households by income
Equivalised disposable household income - P40 = $714 in 2015-16 for VIC - http://www.abs.gov.au/AUSSTATS/abs@.nsf/DetailsPage/6523.02015-16?OpenDocument
hhincwk_mid40 <- hhincwk_mid %>%
filter(inc_mid <= 714)
hhincwk_mid40
Midpoints for rent and mortgages
rentwk_mid <- rentdata %>%
rename(rentwk = `RNTRD Rent (weekly) Ranges`) %>%
distinct(rentwk) %>%
mutate(rentwk = as_factor(rentwk)) %>%
filter(!rentwk %in% c('Not stated', 'Not applicable', 'Total' )) %>%
mutate(rent_low = c(0, 1, 75, 100, 125, 150, 175, 200, 225, 250, 275, 300, 325, 350, 375, 400, 425, 450, 550, 650, 750, 850, 950)) %>%
mutate(rent_high = c(0, 74, 99, 124, 149, 174, 199, 224, 249, 274, 299, 324, 349, 374, 399, 424, 449, 549, 649, 749, 849, 949, 1050)) %>%
mutate(rent_mid = (rent_low + rent_high)/2) %>%
select(rentwk, rent_mid)
rentwk_mid
mortwk_mid <- mortdata %>%
rename(mortmth = `MRERD Mortgage Repayments (monthly) Ranges`) %>%
distinct(mortmth) %>%
mutate(mortmth = as_factor(mortmth)) %>%
filter(!mortmth %in% c('Not stated', 'Not applicable')) %>%
mutate(mort_low = c(0, 1, 150, 300, 450, 600, 800, 1000, 1200, 1400, 1600, 1800, 2000, 2200, 2400, 2600, 3000, 4000, 5000)) %>%
mutate(mortwk_low = mort_low/4) %>%
mutate(mort_high = c(0, 149, 299, 449, 599, 799, 999, 1199, 1399, 1599, 1799, 1999, 2199, 2399, 2599, 2999, 3999, 4999, 5999)) %>%
mutate(mortwk_high = mort_high/4) %>%
mutate(mort_mid = (mort_low + mort_high)/2) %>%
mutate(mortwk_mid = (mortwk_low + mortwk_high)/2) %>%
select(mortmth, mort_mid, mortwk_mid)
mortwk_mid
Joining
#joining the data ####
rent_join <- left_join(hhincwk_mid40, rent_hh)
Joining, by = "hhincwk"
rent_join <- left_join(rent_join, rentwk_mid)
Joining, by = "rentwk"
rent_join
mort_join <- left_join(hhincwk_mid40, mort_hh)
Joining, by = "hhincwk"
mort_join <- left_join(mort_join, mortwk_mid)
Joining, by = "mortmth"
mort_join
Stress
rentalstress <- rent_join %>%
mutate(prophousing = rent_mid/inc_mid) %>%
mutate(hstress = ifelse(prophousing <= 0.3, 0, hh)) %>%
group_by(sa2) %>%
summarise(lowinc_hh = sum(hh), hstress = sum(hstress))
rentalstress <- left_join(rentalstress, rent_dw, by = "sa2") %>%
select(sa2, dw, lowinc_hh, hstress) %>%
mutate(propstress = hstress/dw)
rentalstress
mortgagestress <- mort_join %>%
mutate(prophousing = mortwk_mid/inc_mid) %>%
mutate(hstress = ifelse(prophousing <= 0.3, 0, hh)) %>%
group_by(sa2) %>%
summarise(lowinc_hh = sum(hh), hstress = sum(hstress))
mortgagestress <- left_join(mortgagestress, mort_dw, by = "sa2") %>%
select(sa2, dw, lowinc_hh, hstress) %>%
mutate(propstress = hstress/dw)
mortgagestress
housingstress_join <- full_join(rentalstress, mortgagestress)
Joining, by = c("sa2", "dw", "lowinc_hh", "hstress", "propstress")
housingstress_sa2 <- housingstress_join %>%
group_by(sa2) %>%
summarise(dw = sum(dw), lowinc_hh = sum(lowinc_hh), hstress = sum(hstress)) %>%
mutate(prop_stress = hstress/dw) %>%
filter(!is.na(prop_stress))
housingstress_sa2
write_csv(housingstress_sa2, "tables_out/housingstress_sa2.csv")
What does it look like?
Most of the SA2s have fewer than 30 per cent of households in housing stress.
ggplot(housingstress_sa2, aes(x = prop_stress)) +
geom_histogram(bins = 50)

The shapefile
gm_shp <- st_read("shp/SA2_2016_GMEL.shp") %>%
clean_names() %>%
select(sa2_name16) %>%
left_join(housingstress_sa2, by = c("sa2_name16" = "sa2")) %>%
mutate(prop_stress = round(prop_stress, 2))
Reading layer `SA2_2016_GMEL' from data source `C:\Users\willi\Desktop\R\HousingAffordabilityData_2016Census\shp\SA2_2016_GMEL.shp' using driver `ESRI Shapefile'
Simple feature collection with 309 features and 12 fields
geometry type: MULTIPOLYGON
dimension: XY
bbox: xmin: 144.3336 ymin: -38.50299 xmax: 145.8784 ymax: -37.1751
epsg (SRID): NA
proj4string: +proj=longlat +ellps=GRS80 +no_defs
Column `sa2_name16`/`sa2` joining factor and character vector, coercing into character vector
The map
Concentrations in the growth areas.
tmap_mode("view")
tmap mode set to interactive viewing
tm_shape(gm_shp) +
tm_polygons("prop_stress")
LS0tDQp0aXRsZTogIkhvdXNpbmcgU3RyZXNzIC0gU0EycyBpbiBHcmVhdGVyIE1lbGJvdXJuZSINCm91dHB1dDogaHRtbF9ub3RlYm9vaw0KLS0tDQoNCiMgSW50cm9kdWN0aW9uDQoNClRyeWluZyB0byBjYWxjdWxhdGUgaG91c2luZyBzdHJlc3MgdXNpbmcgMzAvNDAgYXMgaW4gaGVyZTogIGh0dHBzOi8vd3d3LmFodXJpLmVkdS5hdS9wb2xpY3kvYWh1cmktYnJpZWZzLzIwMTYvMzA0MC1pbmRpY2F0b3IgDQoNCjIwMTYgQ2Vuc3VzIC0gQ291bnRpbmcgRHdlbGxpbmdzLCBQbGFjZSBvZiBFbnVtZXJhdGlvbiAoU0EyKQ0KDQpEYXRhIFNvdXJjZTogQ2Vuc3VzIG9mIFBvcHVsYXRpb24gYW5kIEhvdXNpbmcsIDIwMTYsIFRhYmxlQnVpbGRlcg0KDQpDb3VudGluZzogRHdlbGxpbmdzIExvY2F0aW9uIG9uIENlbnN1cyBOaWdodA0KDQpWYXJpYWJsZXM6DQoNCiogSElFRCBFcXVpdmFsaXNlZCBUb3RhbCBIb3VzZWhvbGQgSW5jb21lICh3ZWVrbHkpDQoqIFJOVFJEIFJlbnQgKHdlZWtseSkgUmFuZ2VzDQoqIE1SRVJEIE1vcnRnYWdlIFJlcGF5bWVudHMgKG1vbnRobHkpIFJhbmdlcw0KDQpgYGB7ciwgd2FybmluZz1GQUxTRSwgbWVzc2FnZSA9IEZBTFNFfQ0KbGlicmFyeSh0aWR5dmVyc2UpDQpsaWJyYXJ5KHJlYWR4bCkNCmxpYnJhcnkoc2YpDQpsaWJyYXJ5KHRtYXApDQpsaWJyYXJ5KGphbml0b3IpDQpsaWJyYXJ5KHNjYWxlcykNCmBgYA0KDQojIyBJbXBvcnRpbmcgdGhlIHJhdyBkYXRhDQoNCmBgYHtyfQ0KIyNvcmlnaW5hbCBmaWxlcyAtIDIwMTYgY2Vuc3VzIGRhdGEgLSBjc3Ygc3RyaW5nIC0gemVyb3Mgc3VwcHJlc3NlZA0KcmVudGRhdGEgPC0gcmVhZF9leGNlbCgic2EyX2RhdGEueGxzeCIsIHNoZWV0ID0gInNhMl9oaWVkX3JudHJkXzJnbWVsXyB6ZXJvc19zdXAiLCByYW5nZSA9ICJBMTE6RjQ5MTA2IikgJT4lIA0KICBmaWx0ZXIoR0NDU0EgPT0gIkdyZWF0ZXIgTWVsYm91cm5lIikgDQoNCm1vcnRkYXRhIDwtIHJlYWRfZXhjZWwoInNhMl9kYXRhLnhsc3giLCBzaGVldCA9ICJzYTJfaGllZF9tcmVyZF8yZ21lbF8gemVyb3Nfc3VwIiwgcmFuZ2UgPSAiQTExOkY1OTcwOCIpICU+JSANCiAgZmlsdGVyKEdDQ1NBID09ICJHcmVhdGVyIE1lbGJvdXJuZSIpDQpgYGANCg0KIyMgVHJhbnNmb3JtaW5nIHRoZSByZW50IGRhdGENCg0KYGBge3J9DQpyZW50IDwtIHJlbnRkYXRhICU+JSANCiAgcmVuYW1lKHNhMiA9IFNBMikgJT4lIA0KICByZW5hbWUoaGhpbmN3ayA9IGBISUVEIEVxdWl2YWxpc2VkIFRvdGFsIEhvdXNlaG9sZCBJbmNvbWUgKHdlZWtseSlgKSAlPiUgDQogIHJlbmFtZShyZW50d2sgPSBgUk5UUkQgUmVudCAod2Vla2x5KSBSYW5nZXNgKSAlPiUgDQogIG11dGF0ZShoaGluY3drID0gYXNfZmFjdG9yKGhoaW5jd2spLCByZW50d2sgPSBhc19mYWN0b3IocmVudHdrKSkgJT4lIA0KICByZW5hbWUoaGggPSBDb3VudCkgJT4lIA0KICBzZWxlY3QoLUNvdW50aW5nKQ0KcmVudA0KDQpyZW50X2R3IDwtIHJlbnQgJT4lDQogIGZpbHRlcihoaGluY3drICE9ICdOb3QgYXBwbGljYWJsZScpICU+JSANCiAgZmlsdGVyKHJlbnR3ayAhPSAnTm90IGFwcGxpY2FibGUnKSAlPiUgDQogIGdyb3VwX2J5KHNhMikgJT4lIA0KICBzdW1tYXJpc2UoZHcgPSBzdW0oaGgpKSANCnJlbnRfZHcgI2ltcHJvdmUgdGhpcyBieSBqdXN0IGdldHRpbmcgdGhlIGR3ZWxsaW5nIGRhdGEgZnJvbSB0aGUgZGF0YXBhY2tzIGFuZCBqb2luaW5nIHRoZW0gb24gYXQgdGhlIGVuZCAtRzMyDQoNCnJlbnRfaGggPC0gcmVudCAlPiUgDQogIGZpbHRlcighaGhpbmN3ayAlaW4lIGMoJ05pbCBpbmNvbWUnLCAnUGFydGlhbCBpbmNvbWUgc3RhdGVkJywgJ0FsbCBpbmNvbWVzIG5vdCBzdGF0ZWQnLCAnTm90IGFwcGxpY2FibGUnKSkgJT4lIA0KICBmaWx0ZXIoIXJlbnR3ayAlaW4lIGMoJ05vdCBzdGF0ZWQnLCAnTm90IGFwcGxpY2FibGUnICkpDQpyZW50X2hoDQpgYGANCg0KIyMgVHJhbnNmb3JtaW5nIHRoZSBtb3J0Z2FnZSBkYXRhDQoNCmBgYHtyfQ0KbW9ydCA8LSBtb3J0ZGF0YSAlPiUgDQogIHJlbmFtZShzYTIgPSBTQTIpICU+JSANCiAgcmVuYW1lKGhoaW5jd2sgPSBgSElFRCBFcXVpdmFsaXNlZCBUb3RhbCBIb3VzZWhvbGQgSW5jb21lICh3ZWVrbHkpYCkgJT4lIA0KICByZW5hbWUobW9ydG10aCA9IGBNUkVSRCBNb3J0Z2FnZSBSZXBheW1lbnRzIChtb250aGx5KSBSYW5nZXNgKSAlPiUgDQogIG11dGF0ZShoaGluY3drID0gYXNfZmFjdG9yKGhoaW5jd2spLCBtb3J0bXRoID0gYXNfZmFjdG9yKG1vcnRtdGgpKSAlPiUgDQogIHJlbmFtZShoaCA9IENvdW50KSAlPiUgDQogIHNlbGVjdCgtQ291bnRpbmcpDQptb3J0DQoNCm1vcnRfZHcgPC0gbW9ydCAlPiUgDQogIGZpbHRlcihoaGluY3drICE9ICdOb3QgYXBwbGljYWJsZScpICU+JSANCiAgZmlsdGVyKG1vcnRtdGggIT0gJ05vdCBhcHBsaWNhYmxlJykgJT4lIA0KICBncm91cF9ieShzYTIpICU+JSANCiAgc3VtbWFyaXNlKGR3ID0gc3VtKGhoKSkgDQptb3J0X2R3ICNhcyBub3RlZCBhYm92ZQ0KDQptb3J0X2hoIDwtIG1vcnQgJT4lIA0KICBmaWx0ZXIoIWhoaW5jd2sgJWluJSBjKCdOaWwgaW5jb21lJywgJ1BhcnRpYWwgaW5jb21lIHN0YXRlZCcsICdBbGwgaW5jb21lcyBub3Qgc3RhdGVkJywgJ05vdCBhcHBsaWNhYmxlJykpICU+JSANCiAgZmlsdGVyKCFtb3J0bXRoICVpbiUgYygnTm90IHN0YXRlZCcsICdOb3QgYXBwbGljYWJsZScpKQ0KbW9ydF9oaA0KYGBgDQoNCiMjIE1pZHBvaW50cyBmb3IgaW5jb21lDQoNCmBgYHtyfQ0KaGhpbmN3a19taWQgPC0gcmVudGRhdGEgJT4lIA0KICByZW5hbWUoc2EyID0gU0EyKSAlPiUgDQogIHJlbmFtZShoaGluY3drID0gYEhJRUQgRXF1aXZhbGlzZWQgVG90YWwgSG91c2Vob2xkIEluY29tZSAod2Vla2x5KWApICU+JSANCiAgbXV0YXRlKGhoaW5jd2sgPSBhc19mYWN0b3IoaGhpbmN3aykpICU+JSANCiAgZGlzdGluY3QoaGhpbmN3aykgJT4lIA0KICBmaWx0ZXIoIWhoaW5jd2sgJWluJSBjKCdOaWwgaW5jb21lJywgJ1BhcnRpYWwgaW5jb21lIHN0YXRlZCcsICdBbGwgaW5jb21lcyBub3Qgc3RhdGVkJywgJ05vdCBhcHBsaWNhYmxlJywgJ1RvdGFsJykpICU+JSANCiAgbXV0YXRlKGluY19sb3cgPSBjKDEsIDE1MCwgMzAwLCA0MDAsIDUwMCwgNjUwLCA4MDAsIDEwMDAsIDEyNTAsIDE1MDAsIDE3NTAsIDIwMDAsIDI1MDAsIDMwMDApKSAlPiUgDQogIG11dGF0ZShpbmNfaGlnaCA9IGMoMTQ5LCAyOTksIDM5OSwgNDk5LCA2NDksIDc5OSwgOTk5LCAxMjQ5LCAxNDk5LCAxNzQ5LCAxOTk5LCAyNDk5LCAyOTk5LCAzNDk5KSkgJT4lIA0KICBtdXRhdGUoaW5jX21pZCA9IChpbmNfbG93K2luY19oaWdoKS8yKSAlPiUgDQogIHNlbGVjdChoaGluY3drLCBpbmNfbWlkKQ0KaGhpbmN3a19taWQgDQpgYGANCg0KRmlsdGVyIHRvIGluY2x1ZGUgb25seSBib3R0b20gNDAgcGVyIGNlbnQgb2YgaG91c2Vob2xkcyBieSBpbmNvbWUNCg0KRXF1aXZhbGlzZWQgZGlzcG9zYWJsZSBob3VzZWhvbGQgaW5jb21lIC0gUDQwID0gJDcxNCAgaW4gMjAxNS0xNiBmb3IgVklDIC0gaHR0cDovL3d3dy5hYnMuZ292LmF1L0FVU1NUQVRTL2Fic0AubnNmL0RldGFpbHNQYWdlLzY1MjMuMDIwMTUtMTY/T3BlbkRvY3VtZW50DQoNCmBgYHtyfQ0KaGhpbmN3a19taWQ0MCA8LSBoaGluY3drX21pZCAlPiUgDQogIGZpbHRlcihpbmNfbWlkIDw9IDcxNCkNCmhoaW5jd2tfbWlkNDANCmBgYA0KDQojIyBNaWRwb2ludHMgZm9yIHJlbnQgYW5kIG1vcnRnYWdlcw0KDQpgYGB7cn0NCnJlbnR3a19taWQgPC0gcmVudGRhdGEgJT4lIA0KICByZW5hbWUocmVudHdrID0gYFJOVFJEIFJlbnQgKHdlZWtseSkgUmFuZ2VzYCkgJT4lIA0KICBkaXN0aW5jdChyZW50d2spICU+JSANCiAgbXV0YXRlKHJlbnR3ayA9IGFzX2ZhY3RvcihyZW50d2spKSAlPiUgDQogIGZpbHRlcighcmVudHdrICVpbiUgYygnTm90IHN0YXRlZCcsICdOb3QgYXBwbGljYWJsZScsICdUb3RhbCcgKSkgJT4lIA0KICBtdXRhdGUocmVudF9sb3cgPSBjKDAsIDEsIDc1LCAxMDAsIDEyNSwgMTUwLCAxNzUsIDIwMCwgMjI1LCAyNTAsIDI3NSwgMzAwLCAzMjUsIDM1MCwgMzc1LCA0MDAsIDQyNSwgNDUwLCA1NTAsIDY1MCwgNzUwLCA4NTAsIDk1MCkpICU+JSANCiAgbXV0YXRlKHJlbnRfaGlnaCA9IGMoMCwgNzQsIDk5LCAxMjQsIDE0OSwgMTc0LCAxOTksIDIyNCwgMjQ5LCAyNzQsIDI5OSwgMzI0LCAzNDksIDM3NCwgMzk5LCA0MjQsIDQ0OSwgNTQ5LCA2NDksIDc0OSwgODQ5LCA5NDksIDEwNTApKSAlPiUgDQogIG11dGF0ZShyZW50X21pZCA9IChyZW50X2xvdyArIHJlbnRfaGlnaCkvMikgJT4lIA0KICBzZWxlY3QocmVudHdrLCByZW50X21pZCkNCnJlbnR3a19taWQNCg0KbW9ydHdrX21pZCA8LSBtb3J0ZGF0YSAlPiUgDQogIHJlbmFtZShtb3J0bXRoID0gYE1SRVJEIE1vcnRnYWdlIFJlcGF5bWVudHMgKG1vbnRobHkpIFJhbmdlc2ApICU+JSANCiAgZGlzdGluY3QobW9ydG10aCkgJT4lIA0KICBtdXRhdGUobW9ydG10aCA9IGFzX2ZhY3Rvcihtb3J0bXRoKSkgJT4lIA0KICBmaWx0ZXIoIW1vcnRtdGggJWluJSBjKCdOb3Qgc3RhdGVkJywgJ05vdCBhcHBsaWNhYmxlJykpICU+JSANCiAgbXV0YXRlKG1vcnRfbG93ID0gYygwLCAxLCAxNTAsIDMwMCwgNDUwLCA2MDAsIDgwMCwgMTAwMCwgMTIwMCwgMTQwMCwgMTYwMCwgMTgwMCwgMjAwMCwgMjIwMCwgMjQwMCwgMjYwMCwgMzAwMCwgNDAwMCwgNTAwMCkpICU+JQ0KICBtdXRhdGUobW9ydHdrX2xvdyA9IG1vcnRfbG93LzQpICU+JSANCiAgbXV0YXRlKG1vcnRfaGlnaCA9IGMoMCwgMTQ5LCAyOTksIDQ0OSwgNTk5LCA3OTksIDk5OSwgMTE5OSwgMTM5OSwgMTU5OSwgMTc5OSwgMTk5OSwgMjE5OSwgMjM5OSwgMjU5OSwgMjk5OSwgMzk5OSwgNDk5OSwgNTk5OSkpICU+JSANCiAgbXV0YXRlKG1vcnR3a19oaWdoID0gbW9ydF9oaWdoLzQpICU+JSANCiAgbXV0YXRlKG1vcnRfbWlkID0gKG1vcnRfbG93ICsgbW9ydF9oaWdoKS8yKSAlPiUgDQogIG11dGF0ZShtb3J0d2tfbWlkID0gKG1vcnR3a19sb3cgKyBtb3J0d2tfaGlnaCkvMikgJT4lIA0KICBzZWxlY3QobW9ydG10aCwgbW9ydF9taWQsIG1vcnR3a19taWQpDQptb3J0d2tfbWlkIA0KYGBgDQoNCiMjIEpvaW5pbmcNCg0KYGBge3J9DQojam9pbmluZyB0aGUgZGF0YSAgIyMjIw0KcmVudF9qb2luIDwtIGxlZnRfam9pbihoaGluY3drX21pZDQwLCByZW50X2hoKQ0KcmVudF9qb2luIDwtIGxlZnRfam9pbihyZW50X2pvaW4sIHJlbnR3a19taWQpDQpyZW50X2pvaW4NCg0KbW9ydF9qb2luIDwtIGxlZnRfam9pbihoaGluY3drX21pZDQwLCBtb3J0X2hoKQ0KbW9ydF9qb2luIDwtIGxlZnRfam9pbihtb3J0X2pvaW4sIG1vcnR3a19taWQpDQptb3J0X2pvaW4NCmBgYA0KDQojIyBTdHJlc3MNCg0KYGBge3J9DQpyZW50YWxzdHJlc3MgPC0gcmVudF9qb2luICU+JSANCiAgbXV0YXRlKHByb3Bob3VzaW5nID0gcmVudF9taWQvaW5jX21pZCkgJT4lIA0KICBtdXRhdGUoaHN0cmVzcyA9IGlmZWxzZShwcm9waG91c2luZyA8PSAwLjMsIDAsIGhoKSkgJT4lIA0KICBncm91cF9ieShzYTIpICU+JSANCiAgc3VtbWFyaXNlKGxvd2luY19oaCA9IHN1bShoaCksIGhzdHJlc3MgPSBzdW0oaHN0cmVzcykpDQpyZW50YWxzdHJlc3MgPC0gbGVmdF9qb2luKHJlbnRhbHN0cmVzcywgcmVudF9kdywgYnkgPSAic2EyIikgJT4lIA0KICBzZWxlY3Qoc2EyLCBkdywgbG93aW5jX2hoLCBoc3RyZXNzKSAlPiUgDQogIG11dGF0ZShwcm9wc3RyZXNzID0gaHN0cmVzcy9kdykNCnJlbnRhbHN0cmVzcw0KDQptb3J0Z2FnZXN0cmVzcyA8LSBtb3J0X2pvaW4gJT4lIA0KICBtdXRhdGUocHJvcGhvdXNpbmcgPSBtb3J0d2tfbWlkL2luY19taWQpICU+JSANCiAgbXV0YXRlKGhzdHJlc3MgPSBpZmVsc2UocHJvcGhvdXNpbmcgPD0gMC4zLCAwLCBoaCkpICU+JSANCiAgZ3JvdXBfYnkoc2EyKSAlPiUgDQogIHN1bW1hcmlzZShsb3dpbmNfaGggPSBzdW0oaGgpLCBoc3RyZXNzID0gc3VtKGhzdHJlc3MpKQ0KbW9ydGdhZ2VzdHJlc3MgPC0gbGVmdF9qb2luKG1vcnRnYWdlc3RyZXNzLCBtb3J0X2R3LCBieSA9ICJzYTIiKSAlPiUgDQogIHNlbGVjdChzYTIsIGR3LCBsb3dpbmNfaGgsIGhzdHJlc3MpICU+JSANCiAgbXV0YXRlKHByb3BzdHJlc3MgPSBoc3RyZXNzL2R3KQ0KbW9ydGdhZ2VzdHJlc3MgDQoNCmhvdXNpbmdzdHJlc3Nfam9pbiA8LSBmdWxsX2pvaW4ocmVudGFsc3RyZXNzLCBtb3J0Z2FnZXN0cmVzcykNCmhvdXNpbmdzdHJlc3Nfc2EyIDwtIGhvdXNpbmdzdHJlc3Nfam9pbiAlPiUgDQogIGdyb3VwX2J5KHNhMikgJT4lIA0KICBzdW1tYXJpc2UoZHcgPSBzdW0oZHcpLCBsb3dpbmNfaGggPSBzdW0obG93aW5jX2hoKSwgaHN0cmVzcyA9IHN1bShoc3RyZXNzKSkgJT4lIA0KICBtdXRhdGUocHJvcF9zdHJlc3MgPSBoc3RyZXNzL2R3KSAlPiUgDQogIGZpbHRlcighaXMubmEocHJvcF9zdHJlc3MpKQ0KaG91c2luZ3N0cmVzc19zYTINCg0Kd3JpdGVfY3N2KGhvdXNpbmdzdHJlc3Nfc2EyLCAidGFibGVzX291dC9ob3VzaW5nc3RyZXNzX3NhMi5jc3YiKQ0KDQpgYGANCg0KIyMgV2hhdCBkb2VzIGl0IGxvb2sgbGlrZT8NCg0KTW9zdCBvZiB0aGUgU0EycyBoYXZlIGZld2VyIHRoYW4gMzAgcGVyIGNlbnQgb2YgaG91c2Vob2xkcyBpbiBob3VzaW5nIHN0cmVzcy4NCg0KYGBge3J9DQpnZ3Bsb3QoaG91c2luZ3N0cmVzc19zYTIsIGFlcyh4ID0gcHJvcF9zdHJlc3MpKSArDQogIGdlb21faGlzdG9ncmFtKGJpbnMgPSA1MCkNCmBgYA0KDQoNCiMjIFRoZSBzaGFwZWZpbGUNCg0KYGBge3J9DQpnbV9zaHAgPC0gc3RfcmVhZCgic2hwL1NBMl8yMDE2X0dNRUwuc2hwIikgJT4lIA0KICBjbGVhbl9uYW1lcygpICU+JSANCiAgc2VsZWN0KHNhMl9uYW1lMTYpICU+JSANCiAgbGVmdF9qb2luKGhvdXNpbmdzdHJlc3Nfc2EyLCBieSA9IGMoInNhMl9uYW1lMTYiID0gInNhMiIpKSAlPiUgDQogIG11dGF0ZShwcm9wX3N0cmVzcyA9IHJvdW5kKHByb3Bfc3RyZXNzLCAyKSkNCmBgYA0KDQojIyBUaGUgbWFwDQoNCkNvbmNlbnRyYXRpb25zIGluIHRoZSBncm93dGggYXJlYXMuDQoNCmBgYHtyfQ0KdG1hcF9tb2RlKCJ2aWV3IikNCg0KdG1fc2hhcGUoZ21fc2hwKSArDQogIHRtX3BvbHlnb25zKCJwcm9wX3N0cmVzcyIpDQpgYGANCg0K